#include "LinkedList.h"

CLinkedList::CLinkedList(void)
{
    m_head = NULL;
    m_size = 0;
}

CLinkedList::~CLinkedList(void)
{
    Clear();
}

void CLinkedList::Append(const Data& data)
{
    NodeEx* newNode = new NodeEx();
    newNode->data = data;
    newNode->next = m_head;
    if (NULL != m_head)
    {
        m_head->prior = newNode;
    }
    m_head = newNode;

    ++m_size;
}

bool CLinkedList::Insert(const Data& data, int key)
{
    NodeEx* node = Get(key);
    if (NULL == node)
    {
        return false;
    }

    NodeEx* newNode = new NodeEx();
    newNode->data = data;
    newNode->prior = node->prior;
    newNode->next = node;
    
    node->prior->next = newNode;
    node->prior = newNode;

    ++m_size;
    return true;
}

bool CLinkedList::Set(const Data& data)
{
    NodeEx* node = Get(data.key);
    if (NULL != node)
    {
        node->data = data;
        return true;
    }

    return false;
}

bool CLinkedList::Delete(int key)
{
    NodeEx* node = Get(key);
    if (NULL == node)
    {
        return false;
    }

    if (NULL != node->prior)
    {
        if (NULL != node->next)
        {
            node->prior->next = node->next->prior;
        }
        else
        {
            node->prior->next = NULL;
        }
    }

    if (NULL != node->next)
    {
        if (NULL != node->prior)
        {
            node->next->prior = node->prior->next;
        }
        else
        {
            node->next->prior = NULL;
        }
    }

    delete node;
    --m_size;

    return true;
}

void CLinkedList::Clear()
{
    NodeEx* node = NULL;
    while(NULL != m_head)
    {
        node = m_head->next;
        delete m_head;
        m_head = node;
    }

    m_size = 0;
}


bool CLinkedList::Prior(Data& data, int key)
{
    NodeEx* node = Get(key);
    if (NULL != node && NULL != node->prior)
    {
        data = node->prior->data;
        return true;
    }

    return false;
}

bool CLinkedList::Next(Data& data, int key)
{
    NodeEx* node = Get(key);
    if (NULL != node && NULL != node->next)
    {
        data = node->next->data;
        return true;
    }

    return false;
}

bool CLinkedList::Get(Data& data, int key)
{
    NodeEx* node = Get(key);
    if (NULL != node)
    {
        data = node->data;
        return true;
    }

    return false;
}

bool CLinkedList::Get(Data& data)
{
    NodeEx* node = Get(data.key);
    if (NULL != node)
    {
        data.satellite = node->data.satellite;
        return true;
    }

    return false;
}

int CLinkedList::GetSize()
{
    return m_size;
}

bool CLinkedList::IsEmpty()
{
    return (NULL == m_head);
}

#ifdef _DEBUG
#include <iostream>
using namespace std;
void CLinkedList::Print()
{
    NodeEx* node = m_head;
    while(NULL != node)
    {
        cout << "key:" << node->data.key << "\t";
        cout << "Value" << node->data.satellite << endl;
        node = node->next;
    }
}
#endif

NodeEx* CLinkedList::Get(int key)
{
    NodeEx* node = m_head;
    while(NULL != node)
    {
        if (node->data.key == key)
        {
            break;
        }

        node = node->next;
    }

    return node;
}